package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import javax.jcr.Repository;
import org.apache.jackrabbit.j2ee.RepositoryAccessServlet;
import org.apache.jackrabbit.util.Text;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.query.Query;
import javax.jcr.query.RowIterator;
import java.text.NumberFormat;
import javax.jcr.query.Row;
import javax.jcr.Node;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import javax.jcr.Value;
import javax.jcr.RepositoryException;

public final class search_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

  private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();

  private static java.util.List _jspx_dependants;

  private javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.AnnotationProcessor _jsp_annotationprocessor;

  public Object getDependants() {
    return _jspx_dependants;
  }

  public void _jspInit() {
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
    _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());
  }

  public void _jspDestroy() {
  }

  public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws java.io.IOException, ServletException {

    PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;
    PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html;charset=UTF-8");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write('\n');

    Repository rep;
    Session jcrSession;
    try {
        rep = RepositoryAccessServlet.getRepository(pageContext.getServletContext());
        jcrSession = rep.login(new SimpleCredentials("anonymous", "".toCharArray()));
    } catch (Throwable e) {
        
      out.write("Error while accessing the repository: <font color=\"red\">");
      out.print( Text.encodeIllegalXMLCharacters(e.getMessage()) );
      out.write("</font><br>");

        
      out.write("Check the configuration or use the <a href=\"admin/\">easy setup</a> wizard.");

        return;
    }
    try {
        String wspName = jcrSession.getWorkspace().getName();
        String q = request.getParameter("q");
        if (q == null) {
            q = "";
        } else {
            q = new String(q.getBytes("ISO-8859-1"), "UTF-8");
        }
        if (request.getParameter("as_q") != null) {
            q += " " + new String(request.getParameter("as_q").getBytes("ISO-8859-1"), "UTF-8");
        }
        String executedIn = "";
        String queryTerms = "";
        String totalResults = "";
        long from = 0;
        long to = 10;
        long total = 0;
        long maxPage = 0;
        long minPage = 0;
        long currentPageIndex = 0;
        List indexes = new ArrayList();
        RowIterator rows = null;
        String suggestedQuery = null;
        if (q != null && q.length() > 0) {
            String stmt;
            if (q.startsWith("related:")) {
                String path = q.substring("related:".length());
                stmt = "//element(*, nt:file)[rep:similar(jcr:content, '" + path + "/jcr:content')]/rep:excerpt(.) order by @jcr:score descending";
                queryTerms = "similar to <b>" + Text.encodeIllegalXMLCharacters(path) + "</b>";
            } else {
                queryTerms = "for <b>" + Text.encodeIllegalXMLCharacters(q) + "</b>";
                q = q.replaceAll("'", "''");
                stmt = "//element(*, nt:file)[jcr:contains(jcr:content, '" + q + "')]/rep:excerpt(.) order by @jcr:score descending";
            }
            Query query = jcrSession.getWorkspace().getQueryManager().createQuery(stmt, Query.XPATH);
            long time = System.currentTimeMillis();
            rows = query.execute().getRows();
            time = System.currentTimeMillis() - time;
            NumberFormat nf = NumberFormat.getNumberInstance();
            nf.setMaximumFractionDigits(2);
            nf.setMinimumFractionDigits(2);
            executedIn = nf.format(((double) time) / 1000d);
            nf.setMaximumFractionDigits(0);
            totalResults = nf.format(rows.getSize());
            if (request.getParameter("start") != null) {
                from = Long.parseLong(request.getParameter("start"));
                try {
                    rows.skip(from);
                } catch (Exception e) {
                    // make sure rows are consumed
                    while (rows.hasNext()) {
                        rows.nextRow();
                    }
                }
            }
            to = Math.min(from + 10, rows.getSize());

            total = rows.getSize();
            maxPage = total / 10L;
            if (total % 10L > 0) {
                maxPage++;
            }
            currentPageIndex = from / 10L;
            maxPage = Math.min(maxPage, currentPageIndex + 10);
            minPage = Math.max(0, currentPageIndex - 10);
            for (long i = minPage; i < maxPage; i++) {
                indexes.add(new Long(i));
            }

            if (total < 10 && !q.startsWith("related:")) {
                try {
                    Value v = jcrSession.getWorkspace().getQueryManager().createQuery(
                            "/jcr:root[rep:spellcheck('" + q + "')]/(rep:spellcheck())",
                            Query.XPATH).execute().getRows().nextRow().getValue("rep:spellcheck()");
                    if (v != null) {
                        suggestedQuery = v.getString();
                    }
                } catch (RepositoryException e) {
                    // ignore
                }
            }
        }
request.setAttribute("title", "Search workspace " + wspName);

      org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "header.jsp", out, false);
      out.write("\n");
      out.write("\n");
      out.write("<form name=\"gs\" method=\"GET\">\n");
      out.write("  <p>\n");
      out.write("    <input type=\"text\" name=\"q\" size=\"41\" maxlength=\"2048\" value=\"");
      out.print( Text.encodeIllegalXMLCharacters(q) );
      out.write("\" title=\"Search\">\n");
      out.write("    <input type=submit value=\"Search\"><br><br>\n");
      out.write("  </p>\n");
      out.write("</form>\n");
 if (rows != null && rows.getSize() == 0) { 
      out.write('\n');
     if (suggestedQuery != null) { 
      out.write("\n");
      out.write("<p><font class=\"p\" color=\"#cc0000\">Did you mean:</font>\n");
      out.write("  <a href=\"search.jsp?q=");
      out.print( Text.encodeIllegalXMLCharacters(suggestedQuery) );
      out.write("\" class=\"p\">\n");
      out.write("    <b><i>");
      out.print( Text.encodeIllegalXMLCharacters(suggestedQuery) );
      out.write("</i></b>\n");
      out.write("  </a><br>\n");
      out.write("</p>\n");
     } 
      out.write("\n");
      out.write("  <p/>Your search - <b>");
      out.print( Text.encodeIllegalXMLCharacters(q) );
      out.write("</b> - did not match any documents.\n");
      out.write("  <br/><br/>Suggestions:\n");
      out.write("  <ul>\n");
      out.write("    <li>Make sure all words are spelled correctly.</li>\n");
      out.write("    <li>Try different keywords.</li>\n");
      out.write("    <li>Try more general keywords.</li>\n");
      out.write("    <li>Try fewer keywords.</li>\n");
      out.write("  </ul>\n");
      out.write("  ");

    } else if (rows != null) {
  
      out.write("\n");
      out.write("  <table border=0 cellpadding=0 cellspacing=0 width=100% class=\"t bt\">\n");
      out.write("    <tr>\n");
      out.write("      <td><font size=-1>Results <b>");
      out.print( from + 1 );
      out.write("</b> - <b>");
      out.print( to );
      out.write("</b> of about <b>");
      out.print( totalResults );
      out.write("</b> ");
      out.print( queryTerms );
      out.write(". (<b>");
      out.print( executedIn );
      out.write("</b> seconds)&nbsp;</font></td></tr>\n");
      out.write("  </table>\n");
 if (suggestedQuery != null) { 
      out.write("\n");
      out.write("  <p>\n");
      out.write("    <font class=\"p\" color=\"#cc0000\">Did you mean:</font>\n");
      out.write("    <a href=\"search.jsp?q=");
      out.print( Text.encodeIllegalXMLCharacters(suggestedQuery) );
      out.write("\" class=\"p\">\n");
      out.write("      <b><i>");
      out.print( Text.encodeIllegalXMLCharacters(suggestedQuery) );
      out.write("</i></b>\n");
      out.write("    </a><br>\n");
      out.write("  </p>\n");
 } 
      out.write("\n");
      out.write("  <div>\n");
      out.write("    ");

      while (rows.hasNext() && rows.getPosition() < to) {
          Row r = rows.nextRow();
          Node file = (Node) jcrSession.getItem(r.getValue("jcr:path").getString());
          Node resource = file.getNode("jcr:content");
          String size = "";
          if (resource.hasProperty("jcr:data")) {
              double length = resource.getProperty("jcr:data").getLength();
              size = String.valueOf(Math.round(Math.ceil(length / 1000d))) + "k";
          }
          DateFormat df = SimpleDateFormat.getDateInstance(SimpleDateFormat.LONG);
          String lastModified = df.format(resource.getProperty("jcr:lastModified").getDate().getTime());
    
      out.write("\n");
      out.write("    <h6><a href=\"");
      out.print( Text.encodeIllegalXMLCharacters(request.getContextPath() + "/repository/" + wspName + file.getPath()) );
      out.write("\" class=l>");
      out.print( Text.encodeIllegalXMLCharacters(file.getName()) );
      out.write("</a></h6>\n");
      out.write("      <table border=0 cellpadding=0 cellspacing=0>\n");
      out.write("        <tr><td><font>");
      out.print( r.getValue("rep:excerpt(jcr:content)").getString() );
      out.write("\n");
      out.write("          ");
      out.print( Text.encodeIllegalXMLCharacters(file.getPath()) );
      out.write(' ');
      out.write('-');
      out.write(' ');
      out.print( size );
      out.write(' ');
      out.write('-');
      out.write(' ');
      out.print( lastModified );
      out.write(" - <nobr><a href=\"");
      out.print( Text.encodeIllegalXMLCharacters(request.getContextPath()) );
      out.write("/search.jsp?q=related:");
      out.print( Text.encodeIllegalXMLCharacters(URLEncoder.encode(file.getPath(), "UTF-8")) );
      out.write("\">Similar pages</a></nobr></font></td>\n");
      out.write("        </tr>\n");
      out.write("      </table>\n");
      out.write("    ");

      } // while
    
      out.write("\n");
      out.write("  </div>\n");
      out.write("\n");
      out.write("  <br clear=all>\n");
      out.write("  ");

    if (indexes.size() > 1) {
  
      out.write("\n");
      out.write("  <div>\n");
      out.write("    <table border=0 cellpadding=0 cellspacing=0 align=center>\n");
      out.write("      <tr>\n");
      out.write("        <td><font size=-1>Result&nbsp;Page:&nbsp;\n");
      out.write("        ");

        if (currentPageIndex != ((Long) indexes.get(0)).longValue()) {
            
      out.write("<td nowrap align=right><a href=search.jsp?q=");
      out.print( Text.encodeIllegalXMLCharacters(q) );
      out.write("&start=");
      out.print( (currentPageIndex - 1) * 10 );
      out.write(">Previous</a>");

        } else {
            
      out.write("<td nowrap ><font size=-1>");

        }
        for (Iterator it = indexes.iterator(); it.hasNext(); ) {
            long pageIdx = ((Long) it.next()).longValue();
            if (pageIdx == currentPageIndex) {
                
      out.write("<td nowrap><font size=-1>");
      out.print( pageIdx + 1 );

            } else {
                
      out.write("<td nowrap><font size=-1><a href=search.jsp?q=");
      out.print( Text.encodeIllegalXMLCharacters(q) );
      out.write("&start=");
      out.print( pageIdx * 10 );
      out.write('>');
      out.print( pageIdx + 1 );
      out.write("</a>");

            }
        }
        if (currentPageIndex < (maxPage - 1)) {
            
      out.write("<td nowrap><font size=-1><a href=search.jsp?q=");
      out.print( Text.encodeIllegalXMLCharacters(q) );
      out.write("&start=");
      out.print( (currentPageIndex + 1) * 10 );
      out.write(">Next</a>");

        } else {
            
      out.write("<td nowrap >");

        }
        
      out.write("\n");
      out.write("    </table>\n");
      out.write("  </div>\n");
      out.write("  ");

    }
  
      out.write("\n");
      out.write("\n");
      out.write("\n");
      out.write("    <br clear=all><br>\n");
      out.write("    <table>\n");
      out.write("      <tr><td><br><form method=GET action=");
      out.print( Text.encodeIllegalXMLCharacters(request.getContextPath()) );
      out.write("/search.jsp>\n");
      out.write("          <font size=-1><input type=text name=q size=31 maxlength=2048 value=\"");
      out.print( Text.encodeIllegalXMLCharacters(q) );
      out.write("\" title=\"Search\"> <input type=submit value=\"Search\">\n");
      out.write("          </font></form>\n");
      out.write("        <br><font size=-1>\n");
      out.write("        <a href=\"");
      out.print( Text.encodeIllegalXMLCharacters(request.getContextPath()) );
      out.write("/swr.jsp?q=");
      out.print( Text.encodeIllegalXMLCharacters(q) );
      out.write("&swrnum=");
      out.print( rows.getSize() );
      out.write("\">Search&nbsp;within&nbsp;results</a> | <a href=\"http://issues.apache.org/jira/browse/JCR\" target=_blank>Dissatisfied? Help us improve</a></font><br>\n");
      out.write("        <br>\n");
      out.write("      </td></tr>\n");
      out.write("    </table>\n");
      out.write("\n");
      out.write("  ");

    } // if (rows != null)

    String tableClass = "";
    if (rows != null && rows.getSize() == 0) {
        tableClass = " class=\"t n bt\"";
    }
  
      out.write('\n');
      org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "footer.jsp", out, false);
      out.write('\n');

    } finally {
        if (jcrSession != null) {
            jcrSession.logout();
        }
    }

    } catch (Throwable t) {
      if (!(t instanceof SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try { out.clearBuffer(); } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}
